/*
*  d -> destination
*  s -> source
*  h -> height
*  w ->width
* */

/* 90度的旋转,大小不变,实现原理暂时没明白*/
export const drawRotate=function(cvs,img,degree){

    let ctx = cvs.getContext("2d");
    switch(degree){
        case -270:
        case 90:
            cvs.width = img.naturalHeight;
            cvs.height = img.naturalWidth;
            ctx.clearRect(0,0,cvs.width,cvs.height);
            ctx.save();
            ctx.translate(0,0);
            ctx.rotate(degree*Math.PI/180);
            ctx.drawImage(img,0,-img.naturalHeight);
            break;
        case -180:
        case 180:
            cvs.width = img.naturalWidth;
            cvs.height = img.naturalHeight;
            ctx.clearRect(0,0,cvs.width,cvs.height);
            ctx.save();
            ctx.rotate(degree*Math.PI/180);
            ctx.drawImage(img, -img.naturalWidth, -img.naturalHeight);
            break;
        case -90:
        case 270:
            cvs.width = img.naturalHeight;
            cvs.height = img.naturalWidth;
            ctx.clearRect(0,0,cvs.width,cvs.height);
            ctx.save();
            ctx.rotate(degree*Math.PI/180);
            ctx.drawImage(img, -img.naturalWidth,0);
            break;
        default:
            cvs.width = img.naturalWidth;
            cvs.height = img.naturalHeight;
            ctx.clearRect(0,0,cvs.width,cvs.height);
            ctx.save();
            ctx.rotate(degree*Math.PI/180);
            ctx.drawImage(img, 0, 0);
    }
    ctx.restore();

}
/*
*   图片的一维数组转换成 矩阵 形式
* */
export const getImageMatrix=function(imgData){
    let total = imgData.data.length/4;
    let matrix =[];
    let row=[];
    for(let i = 0;i<total;i++){
        let pix =  [];
        pix[0] = imgData.data[i*4];
        pix[1] =imgData.data[i*4+1];
        pix[2] =imgData.data[i*4+2];
        pix[3] =imgData.data[i*4+3];
        row.push(pix);
        if((i+1)%imgData.width ==0){
            matrix.push(row);
            row = [];
        }
    }
    return matrix;
};

/*
* 二维图像数据转换成一维图像数据
* */
export const toImageData=function(imageData,matrix){
    let [dH,dW]= [matrix.length,matrix[0].length];
    for(let i = 0;i<dH;i++){
        for(let j=0;j<dW;j++){
            imageData.data[(i*dW+j)*4]= matrix[i][j][0];
            imageData.data[(i*dW+j)*4+1]= matrix[i][j][1];
            imageData.data[(i*dW+j)*4+2]= matrix[i][j][2];
            imageData.data[(i*dW+j)*4+3]= matrix[i][j][3];
        }
    }
};

/*以下算法 都是 通过 matrix 实现的 */
/*
	* 暂时只支持 90度转
	*  direct 1 & -3 90, 2&-2 180 ,3 & -1 : 270
	* */
export const rotate=function(matrix,direct){
    let [width,height] = [matrix[0].length,matrix.length];
    let newMatrix = [];
    let [newW,newH] = [width,height];
    switch(direct){
        case -1:
        case 3:
            [newW,newH] = [height,width];
            for(let k =0 ;k<newH;k++)
                newMatrix.push([]);
            for(let i= 0;i<newH;i++){
                for(let j=0;j<newW;j++){
                    newMatrix[i][j]=matrix[j][newH-i-1];
                }
            }
            break;
        case 2:
        case -2:
            for(let k =0 ;k<newH;k++)
                newMatrix.push([]);
            for(let i= 0;i<newH;i++){
                for(let j=0;j<newW;j++){
                    newMatrix[i][j]=matrix[newH-i-1][newW-j-1];
                }
            }
            break;
        case 1:
        case -3:
            [newW,newH] = [height,width];
            for(let k =0 ;k<newH;k++)
                newMatrix.push([]);
            for(let i= 0;i<newH;i++){
                for(let j=0;j<newW;j++){
                    newMatrix[i][j]=matrix[newW-j-1][i];
                }
            }
            break;
    }
    return newMatrix.length==0? matrix:newMatrix;
}

export const scale = function(dW,dH,matrix) {
    let newMatrix = [];
    for(let y=0;y<dH;y++){
        let row =[];
        for(let x=0;x<dW;x++){
            row.push(interpolation(dW,dH,x,y,matrix));
            //row.push(matrix[y][x]);
        }
        newMatrix.push(row);
    }
    return newMatrix;
};


/*双线性插值*/
const interpolation=function (dW, dH, dX,dY, matrix){
    let sW = matrix[0].length;
    let sH = matrix.length;
    let sX = (dX + 0.5) * sW / dW - 0.5;
    let sY = (dY + 0.5) * sH / dH - 0.5;
    let sX1 = Math.floor(sX);
    let sX2 = Math.floor(sX + 0.5);
    let sY1 = Math.floor(sY);
    let sY2 = Math.floor(sY + 0.5);
    sX1 = sX1 < 0 ? 0 : sX1;
    sY1 = sY1 < 0 ? 0 : sY1;

    sX1 = sX1 < sW - 1 ? sX1 : sW - 1;
    sY1 = sY1 < sH - 1 ? sY1 : sH - 1;

    sX2 = sX2 < sW - 1 ? sX2 : sW - 1;
    sY2 = sY2 < sH - 1 ? sY2 : sH - 1;

    // 取出原矩阵中对应四个点的值
    let p11 = matrix[sY1][sX1];
    let p12 = matrix[sY2][sX1];
    let p21 = matrix[sY1][sX2];
    let p22 = matrix[sY2][sX2];
    /*计算该点的值
    * srgb 每层都取四个点的均值
    * */
    let pix = [];
    pix[0] = Math.round((p11[0]+p12[0]+p21[0]+p22[0])/4);
    pix[1] = Math.round((p11[1]+p12[1]+p21[1]+p22[1])/4);
    pix[2] = Math.round((p11[2]+p12[2]+p21[2]+p22[2])/4);
    pix[3] = Math.round((p11[3]+p12[3]+p21[3]+p22[3])/4);
    return pix;
};
/*
*  x ,y  表示位置 可为负数
*  w width
*  h height
* */

export const clip =function(matrix,x,y,w,h){
    let clipMatrix = [];
    let empty = [0,0,0,0];
    let srcW = matrix[0].length;
    let srcH = matrix.length;
    for(let k =0 ;k<h;k++)
        clipMatrix.push([]);
    for(let i =0;i<h;i++){
        for(let j = 0;j<w;j++){
            let srcX = j+x;
            let srcY = i+y;
            if(srcX<0 || srcY <0 || srcX>=srcW || srcY>=srcH )
                clipMatrix[i][j] = empty;
            else
                clipMatrix[i][j] = matrix[srcY][srcX];
        }
    }
    return clipMatrix;
};

export const addMark =function(matrix,markMatrix,position ='bottom-right'){
    let [srcH,srcW] = [matrix.length,matrix[0].length];
    let [mH,mW] = [markMatrix.length,markMatrix[0].length];
    let posX = 0;
    let posY = 0;
    switch(position){
        case 'top-left':
            break;
        case 'top-right':
            posX = srcW-mW;
            break;
        case 'bottom-left':
            posY = srcH-mH;
            break;
        case 'bottom-right':
            posX = srcW-mW;
            posY = srcH-mH;
            break;
        case 'center':
            posX = Math.floor((srcW-mW)/2);
            posY = Math.floor((srcH-mH)/2);
            break;
    }

    for(let i = 0;i<mH;i++){
        for(let j=0;j<mW;j++){
            let transparent = false;
            let pix = markMatrix[i][j];
            if(!pix[0] && !pix[1] && !pix[2] && !pix[3])
                transparent = true;
            if(!transparent && matrix[i+posY][j+posX]){
                let newPix = [];
                let oldPix = matrix[i+posY][j+posX];
            /*  newPix[0] = oldPix[0];
                newPix[1] = oldPix[1];
                newPix[2] = oldPix[2];
                newPix[3] = oldPix[3];*/
                newPix[0] = Math.round(oldPix[0]*0.7+pix[0]*0.3);
                newPix[1] = Math.round(oldPix[1]*0.7+pix[1]*0.3);
                newPix[2] = Math.round(oldPix[2]*0.7+pix[2]*0.3);
                newPix[3] = Math.round(oldPix[3]*0.7+pix[3]*0.3);
                matrix[i+posY][j+posX] = newPix;
            }
        }
    }
};

export const canvasToBlob =function (cvs,type='png'){
    let data = cvs.toDataURL("image/"+type);
    let  arr = data.split(','), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], {type:mime});
};

// img base64 img to Blob;
export const imgBase64ToBlob =function(img){
    let data = img.src;
    let  arr = data.split(','), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], {type:mime});
}


export const canvasPurify = function(cvs,rgb){
    let ctx = cvs.getContext("2d");
    let imgData = ctx.getImageData(0,0,cvs.width,cvs.height)
    let total = imgData.data.length/4;
    for(let i = 0;i<total;i++){
        if(imgData.data[i*4+0] ==0 && imgData.data[i*4+1] ==0 && imgData.data[i*4+2]==0 && imgData.data[i*4+3]==0 )
            break;
        if( !(imgData.data[i*4+1] ==rgb[1]
            && imgData.data[i*4+2]==rgb[2] && imgData.data[i*4+3]==3)){
            imgData.data[i*4] =0 ;
            imgData.data[i*4+1] =0 ;
            imgData.data[i*4+2] =0 ;
            imgData.data[i*4+3]==0;
        }

    }

    ctx.putImageData(imgData,0,0);
    //return imgData;
};


export const imageRotate= function(img,degree){
    let cvs = document.createElement("canvas");
    //let cvs = document.getElementById("canvas1");
    drawRotate(cvs,img,degree);
    img.src = cvs.toDataURL();
    cvs = null;
}

//切记 只能是分辨率很小的图片
export const cvsToMatrix =function(cvs){
    return getImageMatrix(cvs.getContext("2d").getImageData(0,0,cvs.width,cvs.height));
};


export const clipImage =function(img,x,y,w,h){
    let cvs = document.createElement("canvas");
    let ctx = cvs.getContext("2d");
    cvs.width = w;
    cvs.height = h;
    ctx.drawImage(img,x,y,w,h,0,0,w,h);
    return cvs ;
};

export const getThumbnail = function(img,size){
    let [w,h] = size.split('*');
    if(!h)
        h = w;
    let _w_rate = img.naturalWidth/w;
    let _h_rate = img.naturalHeight/h;
    if(_w_rate<_h_rate)
        w = Math.round(img.naturalWidth/_h_rate);
    else
        h = Math.round(img.naturalHeight/_w_rate);
    let cvs = document.createElement("canvas");
    let ctx = cvs.getContext("2d");
    cvs.width = w;
    cvs.height = h;
    ctx.drawImage(img,0,0,img.naturalWidth,img.naturalHeight,0,0,w,h);
    return cvs ;
}

/*
*  1 截取 图片的内容 转换成矩阵
*  2 水印的图片 转换成 矩阵
*  3  图片矩阵和水印矩阵 计算 返回处理后的矩阵
*  4  处理后的矩阵转换成 canvas
*  5 图片 转换成 canvas
*  6 图片canvas 加上 水印 canvas
*
* */
export const addMarkByImage =function(img,markImg,markPos='down-right'){
    let [x,y,w,h] = [0,0,markImg.width,markImg.height];
    switch(markPos){
        case 'top-right':
            x = img.width-w-1;
            break;
        case 'bottom-left':
            y = img.height-h-1;
            break;
        case 'bottom-right':
            x = img.width-w-1;
            y = img.height-h-1;
            break;
        case 'center':
            x = Math.floor((img.width-w-1)/2);
            y = Math.floor((img.height-1)/2);
            break;
    }

    let imgClipMatrix = cvsToMatrix(clipImage(img,x,y,w,h));
    let markMatrix = cvsToMatrix(clipImage(markImg,x,y,w,h));
    //增加水印
    addMark(imgClipMatrix,markMatrix,markPos);
    let markCvs = document.createElement("canvas");
    markCvs.width = w;
    markCvs.height = h;
    markCtx = markCvs.getContext("2d");
    let imageData = markCtx.createImageData(w,h);
    toImageData(imageData,imgClipMatrix);
    markCtx.putImageData(imageData,0,0);
    let imgCvs  = document.createElement("canvas");
    let imgCtx = imgCvs.getContext("2d");
    imgCvs.width = img.width;
    imgCvs.height = img.height;
    imgCtx.drawImage(img,0,0);
    imgCtx.drawImage(markCvs,0,0,w,h,x,y,w,h);
    img.src = canvasToBlob(imgCvs);
}

/*
*  1 截取 图片的内容 转换成矩阵
*  2 水印的图片 转换成 矩阵
*  3  图片矩阵和水印矩阵 计算 返回处理后的矩阵
*  4  处理后的矩阵转换成 canvas
*  5 图片 转换成 canvas
*  6 图片canvas 加上 水印 canvas
*
* */
export const addMarkByMatrix =function(img,markMatrix,markPos='bottom-right'){
    let [x,y,w,h] = [0,0,markMatrix[0].length,markMatrix.length];
    switch(markPos){
        case 'top-right':
            x = img.width-w-1;
            break;
        case 'bottom-left':
            y = img.height-h-1;
            break;
        case 'bottom-right':
            x = img.width-w-1;
            y = img.height-h-1;
            break;
        case 'center':
            x = Math.floor((img.width-w-1)/2);
            y = Math.floor((img.height-1)/2);
            break;
    }

    let imgClipMatrix = cvsToMatrix(clipImage(img,x,y,w,h));
    //let markMatrix = cvsToMatrix(clipImage(markImg,x,y,w,h));
    //增加水印
    addMark(imgClipMatrix,markMatrix,markPos);
    let markCvs = document.createElement("canvas");
    markCvs.width = w;
    markCvs.height = h;
    let markCtx = markCvs.getContext("2d");
    let imageData = markCtx.createImageData(w,h);
    toImageData(imageData,imgClipMatrix);
    markCtx.putImageData(imageData,0,0);
    let imgCvs  = document.createElement("canvas");
    let imgCtx = imgCvs.getContext("2d");
    imgCvs.width = img.width;
    imgCvs.height = img.height;
    imgCtx.drawImage(img,0,0);
    imgCtx.drawImage(markCvs,0,0,w,h,x,y,w,h);
    return imgCvs.toDataURL();
    //img.src= imgCvs.toDataURL();
    //img.src = canvasToBlob(imgCvs);
}
